package com.laity.single;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author: Laity
 * @Project: JavaLaity
 * @Package: com.laity.single.StaticInnerClassSingleton
 * @Date: 2023年11月20日 22:48
 * @Description: 静态内部类实现
 * 单例中最重要的思想是 构造器私有化，别人就不能 new这个对象，保证内存中只有一个对象
 */

public class StaticInnerClassSingleton {
    private StaticInnerClassSingleton() {
    }

    public static StaticInnerClassSingleton getInstance(){
        // 调用内部类的实现
        return SingletonHolder.STATIC_INNER_CLASS_SINGLETON;
    }

    public static class SingletonHolder{
        // 内部类调用外部类
        private static final  StaticInnerClassSingleton STATIC_INNER_CLASS_SINGLETON = new StaticInnerClassSingleton();
    }

    // 但是不安全，来来来，看我炫技 - 反射!
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        StaticInnerClassSingleton instance = StaticInnerClassSingleton.getInstance();
        // 反射破坏单例 - 空参构造器
        Constructor<StaticInnerClassSingleton> declaredConstructor = StaticInnerClassSingleton.class.getDeclaredConstructor(null);
        // 这样就无视了私有的构造器
        declaredConstructor.setAccessible(true);
        StaticInnerClassSingleton staticInnerClassSingleton = declaredConstructor.newInstance();
        System.out.println(instance);
        System.out.println(staticInnerClassSingleton);
        /*
        com.laity.single.StaticInnerClassSingleton@52cc8049
        com.laity.single.StaticInnerClassSingleton@5b6f7412
        可以看出两个值是不一致的，如果按照单例来讲，两个值应该是一样的（”保证内存中只有一个对象”）
         */
        System.out.println("=======================hashCode====================");
        System.out.println(instance.hashCode());
        System.out.println(staticInnerClassSingleton.hashCode());
        /*
        1389133897
        1534030866
        也是不一样的
         */
    }
}
